package com.web.kftsdk.api;

import com.lycheepay.gateway.client.KftBaseService;
import com.lycheepay.gateway.client.http.HttpUploadFile;
import com.lycheepay.gateway.client.security.KeystoreSignProvider;
import com.lycheepay.gateway.client.security.SignProvider;
import com.lycheepay.gateway.client.util.Bytes;
import com.web.kftsdk.bean.KftTransactionType;
import com.web.kftsdk.bean.MerchantTypeEnum;
import com.web.kftsdk.common.api.BasePayService;
import com.web.kftsdk.common.api.PayConfigStorage;
import com.web.kftsdk.common.bean.PayRes;
import com.web.kftsdk.common.exception.PayErrorException;
import com.web.kftsdk.common.http.HttpConfigStorage;
import com.web.kftsdk.common.util.ValidationUtil;
import com.web.kftsdk.common.util.sign.SignUtils;
import com.web.kftsdk.common.util.str.StringUtils;

import com.jcraft.jsch.SftpException;
import com.web.kftsdk.entity.*;
import com.web.kftsdk.utils.KftUtil;
import com.web.kftsdk.utils.SFTPUtil;
import com.web.kftsdk.utils.ZipUtil;
import com.web.utils.HttpClientBase;
import com.web.utils.JsonStringToObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;;

import java.io.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 快付通支付服务
 *
 * @author xukk
 */
@Slf4j
public class KftPayService extends BasePayService {
    KftBaseService kftBaseService;

    public KftPayService(PayConfigStorage payConfigStorage) {
        super(payConfigStorage);
    }

    public KftPayService(PayConfigStorage payConfigStorage, HttpConfigStorage configStorage) {
        super(payConfigStorage, configStorage);
    }


    @Override
    public String sign(String content, String charset) throws PayErrorException {
        return SignUtils.valueOf(payConfigStorage.getSignType()).createSign(content, payConfigStorage.getKeyPrivate(), charset);
    }

    @Override
    public boolean verify(Map<String, String> params) throws PayErrorException {
        return super.verify(params);
    }

    /**
     * 打包
     *
     * @param merchantId        商户ID
     * @param merchantTypeEnum  商户类型
     * @param identificationReq 图片地址
     * @return
     */
    public PayRes pack(String merchantId, MerchantTypeEnum merchantTypeEnum, IdentificationReq identificationReq) {
        PayRes payRes = PayRes.Map();
        try {
            KftPayConfigStorage kftPayConfigStorage = (KftPayConfigStorage) payConfigStorage;
            String datetime = new SimpleDateFormat("YYYYMMddHHmmss").format(new Date());
            String fileName = datetime + (new Random().nextInt(900) + 100) + ".zip";
            String uuid = UUID.randomUUID().toString();
            String source = kftPayConfigStorage.getPackPath() + "/" + uuid;
            CertInfoEntity certInfoEntity = CertInfoEntity.builder()
                    .merchant(CertInfoEntity.Merchant.builder().merchantId(merchantId).build())
                    .certs(KftUtil.getCerts(requestTemplate, source, merchantTypeEnum, identificationReq)).build();
            KftUtil.generateInfo(source, certInfoEntity);
            String zipPath = kftPayConfigStorage.getPackPath() + "/" + fileName;
            ZipUtil.zip(source, zipPath);
            payRes.success().put("path", zipPath).put("date", datetime.substring(0, 8)).put("name", fileName);
        } catch (Exception e) {
            payRes.failure(e.getMessage());
        }
        return payRes;
    }

    /**
     * sftp上传
     *
     * @param date     日期
     * @param filePath 路径
     * @param fileName 名称
     * @return
     */
    public PayRes sftp(String date, String filePath, String fileName) {
        PayRes payRes = PayRes.Custom();
        try {
            KftPayConfigStorage kftPayConfigStorage = (KftPayConfigStorage) payConfigStorage;
            System.out.println("上传文件路径："+filePath);
            FileInputStream fileInputStream = new FileInputStream(filePath);
            sftpUpload(kftPayConfigStorage.getSftpPath() + "/" + date, fileName, fileInputStream);
            payRes.success("上传成功!").put("certPath",  date+"/"+fileName)
                    .put("certDigest"
                            ,md5File(filePath));
        } catch (Exception e) {
            payRes.failure(e.getMessage());
        }
        return payRes;
    }

    String md5File(String fileName) {
        String fileDegist = null;
        try {
            fileDegist = md5AndBase64(fileName);
            System.out.println("fileDegist:" + fileDegist);
            return fileDegist;
        }
        catch (IOException ex) {
            ex.printStackTrace();
            return "";
        }
    }

    // filePath是全路径，支持中文，要是一个存在的文件，如：D:/btp20170621084132.json， E：/文档/btp20170621084132.json
    String md5AndBase64(String filePath) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(filePath);
        byte[] md5Bytes = DigestUtils.md5(fileInputStream);
        String result = new String(Base64.encodeBase64(md5Bytes), "UTF-8");
        IOUtils.closeQuietly(fileInputStream);
        return result;
    }


    private void sftpUpload(String directory, String sftpFileName, InputStream input) throws SftpException {
        KftPayConfigStorage kftPayConfigStorage = (KftPayConfigStorage) payConfigStorage;
        SFTPUtil sftp = new SFTPUtil(kftPayConfigStorage.getSftpUsername(), kftPayConfigStorage.getSftpPassword(), kftPayConfigStorage.getSftpHost(), kftPayConfigStorage.getSftpPort());
        sftp.login();
        sftp.upload(directory, sftpFileName, input);
        sftp.logout();
    }

    /**
     * sftp下载
     * @param directory
     * @param downloadFile
     * @param saveFile
     * @throws SftpException
     * @throws FileNotFoundException
     */
    private void sftpDownload(String directory, String downloadFile, String saveFile) throws SftpException,FileNotFoundException{
        KftPayConfigStorage kftPayConfigStorage = (KftPayConfigStorage) payConfigStorage;
        SFTPUtil sftp = new SFTPUtil(kftPayConfigStorage.getSftpUsername(), kftPayConfigStorage.getSftpPassword(), kftPayConfigStorage.getSftpHost(), kftPayConfigStorage.getSftpPort());
        sftp.login();
        sftp.download(directory,downloadFile,saveFile);
        sftp.logout();
    }
    /**
     * 二级商户入驻
     * 同步请求
     *
     * @return
     */
    public PayRes ampSecmerchantAdd(SecmerchantReq secmerchantReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(secmerchantReq, SecmerchantReq.AddCheck.class);
        } catch (PayErrorException e) {
            e.printStackTrace();
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = secmerchantReq.toMap(KftTransactionType.AMP_SECMERCHANT_ADD.getMethod());
        map=createSign(map);
        log.info("请求参数："+map);
        HttpClientBase httpClientBase=new HttpClientBase();
        String res=httpClientBase.doPost(payConfigStorage.getGateWay(),map,"utf-8");
        //SecmerchantRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, SecmerchantRes.class);
        SecmerchantRes res1= JsonStringToObject.transfer(res,SecmerchantRes.class);
        payRes.put("res", res1);
        if (StringUtils.isBlank(res1.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 二级商户更新
     *
     * @param secmerchantReq
     * @return
     */
    public PayRes ampSecmerchantUpdate(SecmerchantReq secmerchantReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(secmerchantReq, SecmerchantReq.UpdateCheck.class);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = secmerchantReq.toMap(KftTransactionType.AMP_SECMERCHANT_UPDDATE.getMethod());
        createSign(map);
        SecmerchantRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, SecmerchantRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 二级商户查询
     *
     * @param secmerchantReq
     * @return
     */
    public PayRes ampSecmerchantQuery(SecmerchantReq secmerchantReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(secmerchantReq, SecmerchantReq.QueryCheck.class);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = secmerchantReq.toMap(KftTransactionType.AMP_SECMERCHANT_QUERY.getMethod());
        createSign(map);
        SecmerchantRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, SecmerchantRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 被动扫码支付
     * 同步+异步
     * 如果同步请求返回状态为“用户付款中“，则需等待用户输入密码。
     * 用户支付成功后，快付通会返回商户支付结果信息，本次通知只会通知一次，异步回调方式参见 2.3.3异步回调方式。
     * 如果一段时间内没有收到异步通知，商户可以调用查询结果查询交易结果。建议每隔8秒查询一次，如果商户主动查询到交易终态结果，系统将不再发送异步通知。
     * 异步回调类 {@link NotifyRes}
     *
     * @return
     */
    public PayRes kppBdsmPAY(KppBdsmPayReq kppBdsmPayReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppBdsmPayReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppBdsmPayReq.toMap(KftTransactionType.KPP_BDSM_PAY.getMethod());
        createSign(map);
        KppBdsmPayRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppBdsmPayRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 主动扫码支付
     * 同步+异步
     * 如果同步请求返回状态为“用户付款中“，则需等待用户输入密码。
     * 用户支付成功后，快付通会返回商户支付结果信息，本次通知只会通知一次，异步回调方式参见 2.3.3异步回调方式。
     * 如果一段时间内没有收到异步通知，商户可以调用查询结果查询交易结果。建议每隔8秒查询一次，如果商户主动查询到交易终态结果，系统将不再发送异步通知。
     * 异步回调类 {@link NotifyRes}
     *
     * @param kppBdsmPayReq
     * @return
     */
    public PayRes kppZdsmPay(KppZdsmPayReq kppBdsmPayReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppBdsmPayReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppBdsmPayReq.toMap(KftTransactionType.KPP_ZDSM_PAY.getMethod());
        createSign(map);
        KppZdsmPayRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppZdsmPayRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * APP支付
     * 同步+异步
     * 异步回调类 {@link NotifyRes}
     *
     * @param kppAppPayReq
     * @return
     */
    public PayRes kppAppPay(KppAppPayReq kppAppPayReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppAppPayReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppAppPayReq.toMap(KftTransactionType.KPP_APP_PAY.getMethod());
        createSign(map);
        KppAppPayRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppAppPayRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 公众号/生活号（原支付宝服务窗）支付
     * 同步+异步
     * 异步回调类 {@link NotifyRes}
     *
     * @param kppPaPayReq
     * @return
     */
    public PayRes kppPaPay(KppPaPayReq kppPaPayReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppPaPayReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppPaPayReq.toMap(KftTransactionType.KPP_PA_PAY.getMethod());
        createSign(map);
        KppAppPayRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppAppPayRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 公众号/生活号（原支付宝服务窗）预支付下单
     * 同步+异步
     * 异步回调类 {@link NotifyRes}
     *
     * @param kppPaPayReq
     * @return
     */
    public PayRes kppPaPrepay(KppPaPayReq kppPaPayReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppPaPayReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppPaPayReq.toMap(KftTransactionType.KPP_PA_PREPAY.getMethod());
        createSign(map);
        KppAppPayRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppAppPayRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * H5支付
     * 同步+异步
     * 异步回调类 {@link NotifyRes}
     *
     * @return
     */
    public PayRes kppH5Pay(KppH5PayReq kppH5PayReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppH5PayReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppH5PayReq.toMap(KftTransactionType.KPP_H5_PAY.getMethod());
        createSign(map);
        KppH5PayRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppH5PayRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 网银支付 返回请求参数给前端
     * 2.	提交地址:
     * 测试：http://218.17.35.123:8085/cashier-web/ initiative/trade
     * 生产：https://cashier.kftpay.com.cn/initiative/trade
     * 3.	请求限制:
     * 1)	只支持HTTP POST方式提交,提交的参数参见“同步请求参数说明”.
     * 2)	HTTP header参数Content-Type为”application/x-www-form-urlencoded; text/html; charset=utf-8”
     * 3)	HTTP header参数Accept 为” text/html”
     * 4)	商户发送请求时,参数值使用的编码字符集，必须是UTF-8
     * 4.	响应限制:整个响应参数以json格式返回,例如: {"orderNo":"01147102201706280000000010","status":"1","errorCode":"","failureDetails":""}
     *
     * @param kppUnionReq
     * @return
     */
    public PayRes union(KppUnionReq kppUnionReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppUnionReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppUnionReq.toMap();
        createSign(map);
        payRes.setData(map);
        return payRes.success();
    }

    /**
     * 短信快捷收款申请
     *
     * @param kppSmsCollectReq
     * @return
     */
    public PayRes kppSmsCollect(KppSmsCollectReq kppSmsCollectReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppSmsCollectReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppSmsCollectReq.toMap(KftTransactionType.KPP_SMS_COLLECT.getMethod());
        createSign(map);
        KppSmsCollectRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppSmsCollectRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }


    /**
     * 短信快捷收款确认
     *
     * @param kppSmsPayReq
     * @return
     */
    public PayRes kppSmsPay(KppSmsPayReq kppSmsPayReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppSmsPayReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppSmsPayReq.toMap(KftTransactionType.KPP_SMS_PAY.getMethod());
        createSign(map);
        KppSmsPayRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppSmsPayRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 申请退款
     *
     * @param kppRefundReq
     * @return
     */
    public PayRes kppRefund(KppRefundReq kppRefundReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppRefundReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppRefundReq.toMap(KftTransactionType.KPP_REFUND.getMethod());
        createSign(map);
        KppRefundRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppRefundRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 交易查询
     *
     * @param kppTradeRecordQueryReq
     * @return
     */
    public PayRes kppTradeRecordQuery(KppTradeRecordQueryReq kppTradeRecordQueryReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppTradeRecordQueryReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppTradeRecordQueryReq.toMap(KftTransactionType.KPP_TRADE_RECORD_QUERY.getMethod());
        createSign(map);
        KppTradeRecordQueryRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppTradeRecordQueryRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 下载对账文件
     *
     * @param kppReconResultQueryReq
     * @return
     */
    public PayRes kppReconResultQuery(KppReconResultQueryReq kppReconResultQueryReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppReconResultQueryReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppReconResultQueryReq.toMap(KftTransactionType.KPP_RECON_RESULT_QUERY.getMethod());
        createSign(map);
        KppReconResultQueryRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppReconResultQueryRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 担保交易确认
     *
     * @param kppGuarTradeConfirmReq
     * @return
     */
    public PayRes kppGuarTradeConfirm(KppGuarTradeConfirmReq kppGuarTradeConfirmReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppGuarTradeConfirmReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppGuarTradeConfirmReq.toMap(KftTransactionType.KPP_GUAR_TRADE_CONFIRM.getMethod());
        createSign(map);
        KppGuarTradeConfirmRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppGuarTradeConfirmRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 担保交易取消
     *
     * @param kppGuarTradeCancelReq
     * @return
     */
    public PayRes kppGuarTradeCancel(KppGuarTradeCancelReq kppGuarTradeCancelReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppGuarTradeCancelReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppGuarTradeCancelReq.toMap(KftTransactionType.KPP_GUAR_TRADE_CANCEL.getMethod());
        createSign(map);
        KppGuarTradeCancelRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppGuarTradeCancelRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    /**
     * 退款撤销接口
     *
     * @param kppRefundCancelReq
     * @return
     */
    public PayRes kppRefundCancel(KppRefundCancelReq kppRefundCancelReq) {
        PayRes payRes = PayRes.Custom();
        try {
            ValidationUtil.validate(kppRefundCancelReq);
        } catch (PayErrorException e) {
            return payRes.failure().addData(e.getPayError());
        }
        Map<String, String> map = kppRefundCancelReq.toMap(KftTransactionType.KPP_REFUND_CANCEL.getMethod());
        map=createSign(map);
        KppRefundCancelRes res = requestTemplate.postForObject(payConfigStorage.getGateWay(), map, KppRefundCancelRes.class);
        payRes.put("res", res);
        if (StringUtils.isBlank(res.getErrorCode())) {
            payRes.success();
        } else {
            payRes.failure();
        }
        return payRes;
    }

    //生成签名字符串
    public Map createSign(Map<String, String> map) {
       // map= MapTestUtil.mapRemoveWithNullByRecursion(map);
        try {
             map=  signParameters(map,(List)null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(map.get("signatureInfo"));
        return map;
    }


    private Map<String, String> signParameters(Map<String, String> originalParameters, List<HttpUploadFile> uploadFiles) throws Exception {
        ClassLoader classLoader = getClass().getClassLoader();
        SignProvider keystoreSignProvider = new KeystoreSignProvider("PKCS12", classLoader.getResource("pfx.pfx").getFile(),
                "123456".toCharArray(), null, "123456".toCharArray());
        Map<String, String> parameters = paramsFilter(originalParameters);
        this.attachFileDigest(parameters, uploadFiles);
        String prestr = createLinkString(parameters);
        Charset encoding = Charset.forName("UTF-8");
        String encodeBase64String =keystoreSignProvider.sign(prestr.getBytes("UTF-8"), encoding);
        parameters.put("signatureInfo", encodeBase64String);
        parameters.put("signatureAlgorithm", "RSA");
        return parameters;
    }

    private void attachFileDigest(Map<String, String> parameters, List<HttpUploadFile> uploadFiles) throws Exception {
        if(uploadFiles != null && uploadFiles.size() > 0) {
            StringBuilder sb = new StringBuilder();
            Iterator var4 = uploadFiles.iterator();

            while(var4.hasNext()) {
                HttpUploadFile file = (HttpUploadFile)var4.next();
                String md5;
                if(file.getContent() != null) {
                    md5 = Bytes.getMD5(file.getContent(),"UTF-8");
                    sb.append(md5);
                } else {
                    md5 = Bytes.getFileMD5Base64(file.getFile(), "UTF-8");
                    sb.append(md5);
                }
            }
            parameters.put("fileDigest", sb.toString());
        }

    }

    private static Map<String, String> paramsFilter(Map<String, String> parameters) {
        Map<String, String> result = new HashMap(parameters.size());
        if(parameters != null && parameters.size() > 0) {
            String value = null;
            Iterator var3 = parameters.keySet().iterator();

            while(var3.hasNext()) {
                String key = (String)var3.next();
                value = (String)parameters.get(key);
                if(value != null && !"".equals(value) && !key.equalsIgnoreCase("signatureAlgorithm") && !key.equalsIgnoreCase("signatureInfo")) {
                    result.put(key, value);
                }
            }

            return result;
        } else {
            return result;
        }
    }

    private static String createLinkString(Map<String, String> params) {
        List<String> keys = new ArrayList(params.keySet());
        Collections.sort(keys);
        StringBuilder sb = new StringBuilder();
        String key = null;
        String value = null;

        for(int i = 0; i < keys.size(); ++i) {
            key = (String)keys.get(i);
            value = (String)params.get(key);
            sb.append(key).append("=").append(value);
            if(i < keys.size() - 1) {
                sb.append("&");
            }
        }

        return sb.toString();
    }
}
